package org.lizar.util;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 
 * @author shanbao
 * @email  shanbao@yiji.com
 * @since  1.0.0 2015年2月26日 
 * @version 1.0.0
 * @see 
 * @history
 * <table>
 * <tr><td>actor</td> <td>modify</td> <td>date</td></tr>
 * <tr><td>shanbao</td> <td>create</td> <td>2015年2月26日 下午4:23:15</td></tr>
 * <tr></tr>
 * <table>
 */
public class DateUtil {
	
	
	public static String getTodayStr(){
		return new SimpleDateFormat("yyyyMMdd").format(new Date());
	}
	
    public static Date getNextDay(Date now)  {
        Calendar cad = Calendar.getInstance();
        cad.setTime(now);
        cad.add(Calendar.DATE, 1);
        return cad.getTime();
    }
    
    public static Date getStartOfNextDay(Date now)  {
        Calendar cad = Calendar.getInstance();
        cad.setTime(now);
        cad.add(Calendar.DATE, 1);
        cad.set(Calendar.HOUR_OF_DAY, 0);
        cad.set(Calendar.MINUTE, 0);
        cad.set(Calendar.SECOND, 0);
        cad.set(Calendar.MILLISECOND, 0);
        return cad.getTime();
    }
    
    public static Date getYesterDay(Date now)  {
        Calendar cad = Calendar.getInstance();
        cad.setTime(now);
        cad.add(Calendar.DATE, -1);
        return cad.getTime();
    }
	
    public static Date getEndTimeOfTheDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }
    
    public static Date getStartTimeOfTheDate(Date date) {
        if (date == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }
    
    /**
	 * 第一天的开始 1900-01-01 00:00:00。
	 */
	public static final Date FIRST_TIMESTAMP = parse("1900-01-01 00:00:00");
	
	/**
	 * 第一天 1900-01-01，不包含小时、分、秒
	 */
	public static final Date FIRST_DATE = parseDate("1900-01-01");
	
	/**
	 * 一天的开始 00:00:00
	 */
	public static final Date FIRST_TIME = parseTime("00:00:00");
	
	/**
	 * @see Dates#parseTimestamp(String)
	 */
	public static Date parse(String string) {
		return parseTimestamp(string);
	}

	/**
	 * 对字符串进行解析，解析格式为 "yyyy-MM-dd"
	 */
	public static Date parseDate(String string) {
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(string);
		} catch (ParseException e) {
			throw new RuntimeException("source date string miss match [yyyy-MM-dd]", e);
		}
	}
	
	/**
	 * 对字符串进行解析，解析格式为 "yyyy-MM-dd HH:mm:ss"
	 */
	public static Date parseTime(String string) {
		try {
			return new SimpleDateFormat("HH:mm:ss").parse(string);
		} catch (ParseException e) {
			throw new RuntimeException("source date string miss match [HH:mm:ss]", e);
		}
	}

	/**
	 * 对字符串进行解析，解析格式为 "yyyy-MM-dd HH:mm:ss"
	 */
	public static Date parseTimestamp(String string) {
		try {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(string);
		} catch (ParseException e) {
			throw new RuntimeException("source date string miss match [yyyy-MM-dd HH:mm:ss]", e);
		}
	}

	/**
	 * @see Dates#formatTimestamp(Date)
	 */
	public static String format(Date date) {
		return formatTimestamp(date);
	}

	/**
	 * 格式化 {@link Date} 类型，格式化格式为 "yyyy-MM-dd"
	 */
	public static String formatDate(Date date) {
		return new SimpleDateFormat("yyyy-MM-dd").format(date);
	}
	
	/**
	 * 格式化 {@link Date} 类型，格式化格式为 "HH:mm:ss"
	 */
	public static String formatTime(Date date) {
		return new SimpleDateFormat("HH:mm:ss").format(date);
	}

	/**
	 * 格式化 {@link Date} 类型，格式化格式为 "yyyy-MM-dd HH:mm:ss"
	 */
	public static String formatTimestamp(Date date) {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
	}
	
	// //////////////////////////////////////////////////////////////////////////////////
	// ////////////////////////// 以下单个字母的方法
	// //////////////////////////////////////

	/**
	 * 获得年份
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 获得的年份。
	 */
	public static Integer y(Date date) {
		return get(date, Calendar.YEAR);
	}
	
	/**
	 * 
	 * 设置年份。
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @param year 指定的年份。
	 */
	public static Date y(Date date, int year) {
		return set(date, Calendar.YEAR, year);
	}

	/**
	 * 获得月份。
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 获得指定的月份。
	 */
	public static Integer M(Date date) {
		return get(date, Calendar.MONTH) + 1;
	}
	

	/**
	 * 获得一月的第几天。
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 指定的第几天。
	 */
	public static Integer d(Date date) {
		return get(date, Calendar.DATE);
	}
	
	
	/**
	 * 设置为一月的第几天。
	 *  
	 * @param date 指定的 {@link Date} 对象。
	 * @param day 指定的天数。
	 */
	public static Date d(Date date, int day) {
		return set(date, Calendar.DATE, day);
	}

	/**
	 * 获得一天的第几个小时。（二十四小时制）
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 指定的第几个小时。
	 */
	public static Integer H(Date date) {
		return get(date, Calendar.HOUR_OF_DAY);
	}
	
	/**
	 * 设置为一天的第几个小时。（二十四小时制）
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @param hour 指定的小时数。
	 */
	public static Date H(Date date, int hour) {
		return set(date, Calendar.HOUR_OF_DAY, hour);
	}

	/**
	 * 
	 * 获得一天的第几个小时。（十二小时制）<br>
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 获得的小时数。
	 */
	public static Integer h(Date date) {
		return get(date, Calendar.HOUR);
	}
	
	/**
	 * 设置为一天的第几个小时。（十二小时制）。
	 * 
	 * @param date 指定的 {@link Date}
	 * @param hour 小时数
	 */
	public static Date h(Date date, int hour, boolean am) {
		date = set(date, Calendar.HOUR, hour);
		return set(date, Calendar.AM_PM, am ? Calendar.AM : Calendar.PM);
	}
	
	/**
	 * 获得当前时间是否为上午 (am 0~12)
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return true 表示指定为上午。
	 */
	public static boolean am(Date date) {
		return (get(date, Calendar.AM_PM) == Calendar.AM);
	}
	
	/**
	 * 获得当前时间是否为下午 (pm 13~24)
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return true 该对象指定下午。
	 */
	public static boolean pm(Date date) {
		return (get(date, Calendar.AM_PM) == Calendar.PM);
	}

	/**
	 * 获得第几分钟。
	 * 
	 * @param date 指定的 {@link Date}对象
	 * @return 分钟数。
	 */
	public static Integer m(Date date) {
		return get(date, Calendar.MINUTE);
	}
	
	/**
	 * 设置为是第几分钟。
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @param minute 分钟数。
	 */
	public static Date m(Date date, int minute) {
		return set(date, Calendar.MINUTE, minute);
	}

	/**
	 * 获得第几秒钟。
	 * 
	 * @param date 指定的 {@link Date}对象
	 * @return 秒数。
	 */
	public static Integer s(Date date) {
		return get(date, Calendar.SECOND);
	}

	/**
	 * 
	 * 设置为第几秒钟。
	 * 
	 * @param date 指定的 {@link Date}对象
	 * @param second 要设置的秒数。
	 */
	public static Date s(Date date, int second) {
		return set(date, Calendar.SECOND, second);
	}


	/**
	 * 获得第几毫秒。
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 传入的日期对象。
	 */
	public static Integer S(Date date) {
		return get(date, Calendar.MILLISECOND);
	}
	
	/**
	 * 设置为第几毫秒。
	 * 
	 * @param date 指定的 {@link Date} 对象。
	 * @return 传入的日期对象。
	 */
	public static Date S(Date date, int millisecond) {
		return set(date, Calendar.MILLISECOND, millisecond);
	}

	// 一种 Calender 的简易读写方法。
	private static Integer get(Date date, int type) {
		return (date != null) ? calen(date).get(type) : null;
	}
	
	// 一种 Calender 的简易读写方法。
	private static Date set(Date date, int type, int value) {
		if (date != null) {
			Calendar c = calen(date);
			c.set(type, value);
			date = c.getTime();
		}
		return date;
	}

	// 一种 Calender 的 简易获取方法
	private static Calendar calen(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}
	// //////////////////////////////////////////////////////////////////////////////////

	
	public static String format(String pattern, Date datetime) {
		return new SimpleDateFormat(pattern).format(datetime);
	}

	
}
